/**
 * @addtogroup string.h
 * string.h
 * @{
 */
/**
 *@file ofc_string.h
 *@brief 定义标准库常用的跟字符串处理,内存复制等相关函数. 
 *@note ofc库并没有实现这些函数的功能.
 *@author Leo

 *@par          修改日志
 *<table>
 *<tr><th>Date <th>Version <th>Author <th>Description
 *<tr><td>2019-11-14 <td>1.0 <td>Leo <td>创建初始版本
 *<tr><td>2021-07-20 <td>1.1 <td>Leo <td>增加TOfString类
 *<tr><td>2022-05-20 <td>1.2 <td>Leo <td>原先定义的memcpy之类的原型去掉,改成include<string.h>,<linux/string.h>
 *@copyright 杭州鸿泉物联网技术股份有限公司
 */

#ifndef _OFC_STRING_H_
#define _OFC_STRING_H_

#ifdef __KERNEL__
#include <linux/string.h>
#else
#include <string.h>
#endif

#include "ofc_object.h"

#ifdef __cplusplus
extern "C" {
#endif
/*
void *memcpy(void *dst, const void *src, TSize size);
void *memmove(void *dst, const void *src, TSize size);
char *strcpy(char *dst, const char *src);
char *strncpy(char *dst, const char *src, TSize size);
char *strcat(char *dst, const char *src);
char *strncat(char *dst, const char *src, TSize size);
int memcmp(const void *dst, const void *src, TSize size);
int strcmp(const char *dst, const char *src);
int strncmp(const char *dst, const char *src, TSize size);
int strcoll(const char *dst, const char *src);
TSize strxfrm(char *dst, const char *src, TSize size);
void *memchr(const void *s, int c, TSize size);
char *strchr(const char *s, int c);
TSize strcspn(const char *dst, const char *src);
char *strpbrk(const char *dst, const char *src);
char *strrchr(const char *s, int c);
TSize strspn(const char *dst, const char *src);
char *strstr(const char *dst, const char *src);
char *strtok(char *dst, const char *src);
void *memset(void *s, int c, TSize size);
char *strerror(int errnum);
TSize strlen(const char *s);
TSize memicmp(const void *buf1, const void *buf2, TSize count);
*/

/**
 * 将范围为['A'..'Z']范围内的ch转换为小写字符,不在范围内的字符直接返回
 * @param ch: 需要转换的字符
 * @return 小写字符.
 */
char OfLowerChar(char ch);

/**
 * 将范围为['a'..'z']范围内的ch转换为大写字符,不在范围内的字符直接返回
 * @param ch: 需要转换的字符
 * @return 大写字符.
 */
char OfUpperChar(char ch);

/**
 * 比较2个字符串的大小
 * @param str1: 字符串1
 * @param len1: 字符串1的长度
 * @param str2: 字符串2
 * @param len2: 字符串2的长度
 * @param case_sensitive: 是否区分大小写; True: 区分, False: 不区分
 * @return str1 > str2返回值>0, str1 == str2返回0, 其它返回值<0
 */
Int32 OfStrCmp(const char* str1, Int32 len1, const char* str2, Int32 len2, Bool case_sensitive);

/**
 * 字符串对象
 * @note: 字符串对象需要动态内存分配支持
 * @par
 * @code
   TOfString str;
   TOfStringCreate(&str, "abc");

   // ...

   TOfStringDestroy(&str);
 * @endcode
 */

typedef struct TOfStringTag TOfString;

struct TOfStringTag
{
PRIVATE
    Int32 capacity_;  ///< 当前分配的
    Int32 len_;
    char *str_;    
};

/**
 * 字符串的构造函数
 * @param self: 对象实例指针
 * @param str: 字符串的初始值,可以为NULL
 * @return 
 */
void TOfStringCreate(TOfString *self, const char *str);

/**
 * 字符串析构函数
 * @param self: 对象实例指针
 * @return 
 */
void TOfStringDestroy(TOfString *self);

/**
 * 创建TOfString对象
 * @note: 本函数先内存分配一个TOfString对象,并调用构造函数
 * @param str: 字符串的初始值,可以为NULL
 * @return 返回TOfString对象实例;对象需要通过OfFreeObject释放
 */
TOfString *OfCreateString(const char *str);

/**
 * 释放一个TOfString对象
 * @note: 本函数先调用析构函数,并释放str本身的内存
 * @param str: 
 * @return 
 */
void OfFreeString(TOfString *str);

/**
 * 返回c语言类型的字符串
 * @note: 用户不得释放返回字符串的指针
 * @param self: 对象实例指针
 * @return 返回字符串指针,如果字符串为空返回NULL
 */
const char *TOfStringCStr(TOfString *self);

/**
 * 返回c语言类型的字符串
 * @note: 
 *  1. 用户不得释放返回字符串的指针
 *  2. 该函数与TOfStringCStr的区别在于当字符串内容为空时,前者返回NULL,后者返回""
 * @param self: 对象实例指针
 * @return 返回字符串指针,如果字符串为空返回"",而非NULL
 */
const char *TOfStringCStrConst(TOfString *self);

/**
 * 把c语言类型的字符串设置到对象中
 * @param self: 对象实例指针
 * @param str: 需要设置的字符串,可以为NULL
 * @return 
 */
void TOfStringSetCStr(TOfString *self, const char *str);

/**
 * 把字符串设置到对象中
 * @param self: 对象实例指针
 * @param str: 需要设置的字符串,可以为NULL
 * @return
 */
void TOfStringSet(TOfString *self, const TOfString *str);

/**
 * 返回字符串的长度
 * @param self: 对象实例指针
 * @return 字符串的长度
 */
Int32 TOfStringLen(TOfString *self);

/**
 * 清空字符串
 * @param self: 对象实例指针
 * @return 
 */
void TOfStringClear(TOfString *self);

/**
 * 复制一个字符串
 * @note: 返回的字符串为新的字符串,需要用户自行调用OfFreeString释放;
 * @param self: 对象实例指针
 * @return 返回复制的字符串(返回的字符串对象本身不会为NULL,除非内存不够)
 */
TOfString *TOfStringDump(TOfString *self);

/**
 * 从当前字符串中复制一个字串,并创建这个字串
 * @note: 返回的字符串为新的字符串,需要用户自行调用OfFreeString释放;
 * @param self: 对象实例指针
 * @param pos: 字符串的起始位置,字符串中第一个字符位置为1
 * @param count: 复制字符的个数.如果超出范围,则仅复制从pos开始到字符串末尾的字串.
 * @return 返回复制的字符串(返回的字符串对象本身不会为NULL,除非内存不够)
 */
TOfString *TOfStringCopy(TOfString *self, Int32 pos, Int32 count);

/**
 * 把字符串转换成小写
 * @param self: 对象实例指针
 * @return 
 */
void TOfStringLowerCase(TOfString *self);

/**
 * 把字符串转换为大写
 * @param self: 对象实例指针
 * @return 
 */
void TOfStringUpperCase(TOfString *self);

/**
 * 查找子串sub_str在字符串中的位置
 * @note: 字符串区分大小写
 * @param self: 对象实例指针
 * @param sub_str: 需要查找的子串
 * @return 子串在字符串中的位置,第一个位置为1; 如果子串未找到,返回0.
 */
Int32 TOfStringPos(TOfString *self, const char *sub_str);

/**
 * 查找子串sub_str在字符串中的位置,查找从start_pos开始
 * @note: 字符串区分大小写
 * @param self: 对象实例指针
 * @param sub_str: 需要查找的子串
 * @param start_pos: 字符串从start_pos位置开始查找; 起始位置为1
 * @return 子串在字符串中的位置,第一个位置为1; 如果子串未找到,返回0.
 */
Int32 TOfStringPosEx(TOfString *self, const char *sub_str, Int32 start_pos);

/**
 * 查找子串sub_str在字符串中的位置,查找从右边开始.
 * @note: 字符串区分大小写
 * @param self: 对象实例指针
 * @param sub_str: 需要查找的子串
 * @return 子串在字符串中的位置,第一个位置为1; 如果子串未找到,返回0.
 */
Int32 TOfStringRPos(TOfString *self, const char *sub_str);

/**
 * 返回字符c在字符串中的位置
 * @param self: 对象实例指针
 * @param c: 
 * @return 字符在字符串中的位置,第一个位置为1; 如果子串未找到,返回0.
 */
Int32 TOfStringScan(TOfString *self, char c);

/**
 * 返回字符c在字符串中的位置,起始位置从start_pos开始
 * @param self: 对象实例指针
 * @param c: 需要查找的字符
 * @param start_pos: 字符串从start_pos位置开始查找
 * @return 字符在字符串中的位置,第一个位置为1; 如果子串未找到,返回0.
 */
Int32 TOfStringScanEx(TOfString *self, char c, Int32 start_pos);

/**
 * 返回字符c在字符串中的位置,查找从右边开始.
 * @param self: 对象实例指针
 * @param c: 需要查找的字符
 * @return 字符在字符串中的位置,第一个位置为1; 如果子串未找到,返回0.
 */
Int32 TOfStringRScan(TOfString *self, char c);

/**
 * 字符串比较,区分大小写
 * @param self: 对象实例指针
 * @param text: 需要比较的文本内容
 * @return 相等返回0,前者比后者大返回1,否则返回-1;
 */
Int32 TOfStringCompare(TOfString *self, const char *text);

/**
 * 字符串比较,不区分大小写
 * @param self: 对象实例指针
 * @param text: 需要比较的文本内容
 * @return 相等返回0,前者比后者大返回1,否则返回-1;
 */
Int32 TOfStringCompareText(TOfString *self, const char *text);

/**
 * 字符串比较,不区分大小写
 * @param self: 对象实例指针
 * @param text: 需要比较的文本内容
 * @return 两者相同返回True,否则返回False
 */
Bool TOfStringSameText(TOfString *self, const char *text);

/**
 * 去除字符串两边的空白字符串(空白字符为'\0'..' ')
 * @note: 为了效率,本函数产生的空闲空间不会释放,可通过TOfStringPack来释放空闲空间
 * @param self: 对象实例指针
 * @return 
 */
void TOfStringTrim(TOfString *self);

/**
 * 删除字符串中的一个子串
 * @note: 为了效率,本函数产生的空闲空间不会释放,可通过TOfStringPack来释放空闲空间
 * @param self: 对象实例指针
 * @param pos: 子串的起始位置,从1开始
 * @param count: 需要删除的子串长度
 * @return 
 */
void TOfStringDelete(TOfString *self, Int32 pos, Int32 count);

/**
 * 保留字符串中的一个子串,去除字符串中其它的字符
 * @note: 为了效率,本函数产生的空闲空间不会释放,可通过TOfStringPack来释放空闲空间
 * @param self: 对象实例指针
 * @param pos: 子串的起始位置,从1开始
 * @param count: 需要保留的子串长度
 * @return 
 */
void TOfStringRemain(TOfString *self, Int32 pos, Int32 count);

/**
 * 把字符串str插入到当前字符串的pos处
 * @param self: 对象实例指针
 * @param pos: 插入的位置,从1开始
 * @param str: 需要插入的字符串
 * @return 
 */
void TOfStringInsert(TOfString *self, Int32 pos, const char *str);

/**
 * 连接两个字符串,并保存在当前字符串中
 * @param self: 对象实例指针
 * @param str: 需要连接的字符串
 * @return 
 */
void TOfStringCat(TOfString *self, const char *str);

/**
 * 设置一个整型,相当于整型转字符串; value=123; 字符串为:"123"
 * @param self: 对象实例指针
 * @param value: 设置的整型值
 * @return 
 */
void TOfStringSetInt(TOfString *self, Int32 value);

/**
 * 设置一个无符号整型,相当于无符号整型转字符串; value = 0xFFFFFFFF, 字符串为: "4294967295"
 * @param self: 对象实例指针
 * @param value: 设置的整型值
 * @return 
 */
void TOfStringSetUInt(TOfString *self, UInt32 value);

/**
 * 设置一个整型为十六进制字符,相当于整型转十六进制字符串; value = 0xabcd; 字符串为: "abcd"
 * @param self: 对象实例指针
 * @param value: 设置的整型值
 * @return 
 */
void TOfStringSetHex(TOfString *self, UInt32 value);

/**
 * 字符串转整型
 * @param self: 对象实例指针
 * @return 转换的值.如果转换失败返回0
 */
Int32 TOfStringToInt(TOfString *self);

/**
 * 判断字符串是否为一个数值型
 * @param self: 对象实例指针
 * @return 
 */
Bool TOfStringIsNumber(TOfString *self);

/**
 * 压缩空闲空间
 * @param self: 对象实例指针
 * @return 
 */
void TOfStringPack(TOfString *self);

/**
 * 格式化字符串
 * @param self: 对象实例指针
 * @param fmt: 格式串
 * @return 
 */
void TOfStringFormat(TOfString *self, const char *fmt, ...);

#ifdef __cplusplus
}  // extern "C"
#endif

#endif // _OFC_STRING_H_

/**
 * @}
 */
